// 这个文件是一些通用的抽象接口
package cmd

import (
	"fmt"
	"os"

	"github.com/spf13/cobra"
)

// 定义命令操作接口，不同命令需要实现该接口
type IOperation interface {
	Execute(args []string) error
	ArgsValidation(args []string) error
}

// 定义通用命令结构体，不同命令需要嵌入该结构体
// 是一个泛型结构体，T 必须实现 Operation 接口
type GenericCommand[T IOperation] struct {
	cmd       *cobra.Command
	operation T
	use       string
	short     string
	long      string
}

func GenericNewCommand[T IOperation](use, short, long string, op T) *cobra.Command {
	c := &GenericCommand[T]{
		use:       use,
		short:     short,
		operation: op,
		long:      long,
	}

	c.cmd = &cobra.Command{
		Use:   use,
		Short: short,
		Long:  long,
		Run: func(cmd *cobra.Command, args []string) {
			if err := c.operation.ArgsValidation(args); err != nil {
				// when parsing op name
				fmt.Printf("error: when parsing op name %s, %s", c.use, err)
				os.Exit(-1)
			}
			if err := c.operation.Execute(args); err != nil {
				fmt.Printf("error: when executing op %s, %s", c.use, err)
				os.Exit(-1)
			}
		},
	}
	return c.cmd
}
